<template>
  <div class="overflow-auto">

    <div class="z-canvas relative "
         :style="style"
         @dragover="dragover"
         @drop="drop">
      <ZDraggableResizable :w="item.props.width"
                           :h="item.props.height"
                           :x="item.props.x"
                           :y="item.props.y"
                           :minWidth="item.components.width.component.min || 0"
                           :minHeight="item.components.height.component.min || 0"
                           :parent="true"
                           :debug="false"
                           :isConflictCheck="true"
                           v-for="item in sources"
                           :key="item.events.uuid"
                           :draggable="setting.type === 'widget'"
                           :resizable="setting.type === 'widget'"
                           :active="item.events.uuid === uuid && setting.type === 'widget'"
                           @dragging="dragging"
                           @resizing="resizing"
                           @contextmenu.native.prevent="(e) => contextmenu(e,item.events)"
                           @activated="handleActive(item.events.uuid)">
        <XCircle v-bind="item.props" />
      </ZDraggableResizable>
    </div>
  </div>

</template>

<script>
import { getProps } from './utils'
import ZDraggableResizable from '@/components/storybook/z-draggable-resizable'
import Emitter from '@/mixins/emitter'
import { v4 } from 'uuid'
import { toLower, get } from 'lodash'

export default {
  name: 'ZCanvas',
  mixins: [Emitter],
  components: {
    XCircle: () => import('./elements/x-circle/index.vue'),
    ZDraggableResizable
  },
  props: {
    backgroundImage: String,
    setting: {
      type: Object,
      default: () => ({})
    }
  },

  computed: {

    style () {
      const width = this.setting.width ? `${Number(this.setting.width)}px` : 0
      const height = this.setting.height ? `${Number(this.setting.height)}px` : 0
      return {
        width,
        height,
        backgroundImage: `url(${this.setting.bg})`
      }
    },
    sources () {
      return get(this.setting, 'sources', [])
    },
    uuid () {
      return get(this.setting, 'source.events.uuid')
    }
  },

  methods: {
    contextmenu (event, events) {
      if (this.setting.type !== 'widget') {
        return
      }
      this.$contextmenu({
        items: [
          {
            label: 'Delete',
            onClick: () => {
              const sourceIndex = this.setting.sources.findIndex(i => i.events.uuid === events.uuid)
              this.setting.sources.splice(sourceIndex, 1)
              this.$set(this.setting, 'source', {})
              if (this.setting.sources.length > 0) {
                this.$set(this.setting, 'source', this.setting.sources[0])
              }
            }
          }

        ],
        event,
        customClass: 'context-class',
        zIndex: 99999999,
        minWidth: 100
      })
      return false
    },
    dragover (e) {
      e.preventDefault()
    },
    drop (e) {
      this.$nextTick(async () => {
        const { dataTransfer, x: mouseX, y: mouseY } = e
        const component = dataTransfer.getData('component')

        const { x: dropDomX, y: dropDomY } = e.target.getBoundingClientRect()

        const directory = toLower(component)
        const file = await require(`./elements/${directory}/prop`)
        const [components, props] = Object.freeze(getProps(file.default))

        const data = {
          events: {
            uuid: v4(),
            component: component
          },
          props: {
            ...props,
            field: this.setting.field,
            x: mouseX - dropDomX,
            y: mouseY - dropDomY
          },
          components,
          componentKeys: Object.keys(components)
        }
        this.$set(this.setting, 'source', data)
        this.$set(this.setting.sources, this.setting.sources.length, data)
      })
    },
    dragging (x, y) {
      window.requestAnimationFrame(() => {
        this.$set(this.setting.source.props, 'x', x)
        this.$set(this.setting.source.props, 'y', y)
      })
    },

    resizing (x, y, width, height) {
      window.requestAnimationFrame(() => {
        this.$set(this.setting.source.props, 'width', width)
        this.$set(this.setting.source.props, 'height', height)
        this.$set(this.setting.source.props, 'x', x)
        this.$set(this.setting.source.props, 'y', y)
      })
    },
    handleActive (uuid) {
      const sourceIndex = this.setting.sources.findIndex((i) => get(i, 'events.uuid') === uuid)

      this.setting.source = this.setting.sources[sourceIndex]
    }

  }
}
</script>
<style lang="scss" scoped>
.z-canvas {
  background-color: #ffffff;
  background-position: center center;
  background-size: auto 100%;
  background-repeat: no-repeat;
}
</style>
